package com.hundsun.cprs.yyt.service.match.core.command;

import com.hundsun.cprs.yyt.service.match.core.Matching;
import com.hundsun.cprs.yyt.service.match.core.queue.PriceQueue;
import com.hundsun.cprs.yyt.service.match.domain.TradeEntrust;
import com.hundsun.cprs.yyt.service.match.service.ServiceLocate;
import com.hundsun.cprs.yyt.service.trade.domain.TradeCancelFlow;
import com.hundsun.cprs.yyt.service.trade.enums.EnumEntrustCancelStatus;
import com.hundsun.cprs.yyt.util.TradeEntrustBeanUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.math.BigDecimal;
import java.util.Date;
import java.util.concurrent.Executor;

/**
 * 撤单指令
 */
public class CancelEntrustCommand extends BaseCommand implements MatchingCommand {

    private static final Log logger = LogFactory.getLog(CancelEntrustCommand.class);

    private TradeCancelFlow cancelFlow;

    private TradeEntrust tradeEntrust;

    public CancelEntrustCommand(TradeCancelFlow cancelFlow, TradeEntrust tradeEntrust) {
        super();
        this.cancelFlow = cancelFlow;
        this.tradeEntrust = tradeEntrust;
    }

    @Override
    public void perform(Matching matching, Executor executor) {
        // 根据entrust id找到对应的entrust
        Long entrustId = this.tradeEntrust.getId();
        PriceQueue priceCell = tradeEntrust.isBuy() ? matching.getBuyQueue() : matching.getSellQueue();
        tradeEntrust = priceCell.removeEntrustByPriceAndId(BigDecimal.ZERO.longValue(), entrustId);
        if (tradeEntrust == null) {
            // 竟然没有找到订单,那就是说已经全部成交了,撤销失败
            cancelFlow.setCancelAmount(0L);
            cancelFlow.setCancelStatus(EnumEntrustCancelStatus.FAIL.getCode());
            cancelFlow.setCancelTime(new Date());
            cancelFlow.setRemark("委托单已被成交,撤单失败");
            if (logger.isDebugEnabled()) {
                logger.debug(cancelFlow + " alread match success.so cancel is failed");
            }
            executor.execute(new Runnable() {
                public void run() {
                    ServiceLocate.getTradeMatchService().updateCancelFlowStatus(cancelFlow);
                }
            });
            return;
        }

        long surplusEntrustAmount = tradeEntrust.getSurplusEntrustAmount();
        cancelFlow.setCancelAmount(surplusEntrustAmount);
        cancelFlow.setCancelStatus(EnumEntrustCancelStatus.SUCCESS.getCode());
        cancelFlow.setCancelTime(new Date());

        // 减少用户挂单量
        if (tradeEntrust.isBuy()) {
            matching.getQuotes().reduceBuyingAmount(tradeEntrust.getFundAccount(), tradeEntrust.getSurplusEntrustAmount());
        } else {
            matching.getQuotes().reduceSellingAmount(tradeEntrust.getFundAccount(), tradeEntrust.getSurplusEntrustAmount());
        }

        executor.execute(new Runnable() {
            public void run() {
                ServiceLocate.getTradeMatchService().updateCancelFlowAfterSuccess(cancelFlow,TradeEntrustBeanUtil.copyPropertiesFrom(tradeEntrust));
            }
        });
    }

}
